﻿/**
 * @class MapService.Control.ContextMenu
 * @extends OpenLayers.Control
 * Adiciona menu ao clicar com botão direito do mouse no mapa.
 * 
 * Exemplo de uso:
 * 
 *     mapService.map.addControl(new MapService.Control.ContextMenu({
 *     	menu : [{
 *     		text    : 'Selecionar',
 *     		icon    : 'resources/images/selecionar.png',
 *     		handler : function(){
 *     			mapService.selectMode();
 *     		}
 *     	},{
 *     		text    : 'Pan',
 *     		icon    : 'resources/images/pan.png',
 *     		handler : function(){
 *     			mapService.panMode();
 *     		}
 *     	},{
 *     		text    : 'Atualizar',
 *     		icon    : 'resources/images/redo.png',
 *     		handler : function(){
 *     			mapService.refreshMap();
 *     		}
 *     	}, '-' ,{
 *     		text  : 'Zoom',
 *     		menu  : [{
 *     			text    : 'Zoom Box',
 *     			icon    : 'resources/images/zoom.png',
 *     			handler : function(){
 *     				mapService.zoomBoxMode();
 *     			}
 *     		}, '-' ,{
 *     			text    : 'Zoom Inicial',
 *     			icon    : 'resources/images/home.png',
 *     			handler : function(){
 *     				mapService.zoomToHome();
 *     			}
 *     		},{
 *     			text    : 'Zoom Anterior',
 *     			icon    : 'resources/images/preview.png',
 *     			handler : function(){
 *     				mapService.zoomPrevious();
 *     			}
 *     		},{
 *     			text    : 'Próximo Zoom',
 *     			icon    : 'resources/images/nextview.png',
 *     			handler : function(){
 *     				mapService.zoomNext();
 *     			}
 *     		}]
 *     	},{
 *     		text  : 'Visualizar',
 *     		menu  : [{
 *     			text    : 'Distância',
 *     			icon    : 'resources/images/icon-distancia.png',
 *     			handler : function(){
 *     				mapService.measureDistance();
 *     			}
 *     		},{
 *     			text    : 'Área',
 *     			icon    : 'resources/images/icon-area.png',
 *     			handler : function(){
 *     				mapService.measureArea();
 *     			}
 *     		}]
 *     	}]
 *     }));
 */
MapService.Control.ContextMenu = OpenLayers.Class(OpenLayers.Control, {
	divEvents    : null,
	menu         : null,
	onMapMouseUp : null,
	
	draw: function() {
        OpenLayers.Control.prototype.draw.apply(this, arguments);
        
        this.map.viewPortDiv.oncontextmenu = OpenLayers.Function.False;

        this.divEvents = new OpenLayers.Events(this, this.div, null, true,{includeXY: true});
        this.menu = this.menu || [];
        this.onMapMouseUp = OpenLayers.Function.bindAsEventListener(function(e){
    		if (OpenLayers.Event.isRightClick(e)){
    			this.show(e);
    		}else{
    			this.hide(e);
    		}        	
        }, this);

        OpenLayers.Event.observe(this.map.viewPortDiv, "mouseup", this.onMapMouseUp);
		this.divEvents.on({
			"dblclick": this.stopEvent,
			"mousemove": this.stopEvent,
			"mousedown": this.stopEvent,
			"click": this.stopEvent
		});
        
        this.div.style.position= "absolute";
        this.div.style.display= "none";
        
        this.parseMenu(this.div, this.menu);
        
        return this.div;
	},
	
	destroy: function(){
		OpenLayers.Event.stopObserving(this.map.viewPortDiv, "mouseup", this.onMapMouseUp);
		this.divEvents.un({
			"dblclick": this.stopEvent,
			"mousemove": this.stopEvent,
			"mousedown": this.stopEvent,
			"click": this.stopEvent
		});
		return OpenLayers.Control.prototype.destroy.apply(this, arguments);
	},
	
	stopEvent: function(e) {
        OpenLayers.Event.stop(e, true);
        return false;    	
    },
    
    createMenu : function(){
    	var menu = document.createElement('div');
    	menu.style.backgroundColor= "white";
    	menu.style.position= "absolute";
    	menu.style.boxShadow= "3px 3px 5px #4B4B4B";
    	menu.style.MozBoxShadow= "3px 3px 5px #4B4B4B";
    	menu.style.WebkitBoxShadow= "3px 3px 5px #4B4B4B";
    	menu.style.filter= "progid:DXImageTransform.Microsoft.Shadow(Strength=5, Direction=135, Color='#4B4B4B')";
		//menu.style.setAttribute("-ms-filter", "progid:DXImageTransform.Microsoft.Shadow(Strength=5, Direction=135, Color='#4B4B4B')");
		menu.style.border= "solid 1px silver";
		
		return menu;
    },
    
    createSeparator : function(){
	    var sep = document.createElement('span');
	    sep.style.height = "1px";
	    sep.style.display = "block";
	    sep.style.backgroundColor= "silver";
	    sep.style.margin = "0 3px 0 3px";
	    return sep;
    },
    
	createItem : function(options){
		var icon = options.icon || '';
		var handler = options.handler || OpenLayers.Function.Void;
		var text = options.text || "";
		var subMenu = options.menu || [];
		
		var box = document.createElement('span');
		box.style.padding = "2px 1px 2px 1px";
		box.style.display= "block";
		box.style.whiteSpace= "nowrap";
		box.style.position= "relative";
		
		var item = document.createElement('a');
		item.href = "javascript:void(0)";
		item.style.display = "block";
		item.style.position= "relative";
		item.style.padding = "3px 24px 3px 27px";
		item.style.lineHeight= "16px";
		item.style.color= "#222";
		item.style.textDecoration= "none";
		item.style.font= "normal 13px arial,tahoma,sans-serif";
		item.style.cursor= "pointer";
		OpenLayers.Event.observe(item, "mouseup", OpenLayers.Function.bindAsEventListener(handler, this));
	    OpenLayers.Event.observe(item, "mouseover", OpenLayers.Function.bindAsEventListener(function(){
	    	item.style.backgroundColor = "#DDDDDD";
		}, this));
		OpenLayers.Event.observe(item, "mouseout", OpenLayers.Function.bindAsEventListener(function(){
			item.style.backgroundColor = "transparent";
		}, this));
		box.appendChild(item);
		
		
		var img = document.createElement('img');
		img.style.width = "16px";
		img.style.height = "16px";
		img.style.border = "0 none";
		img.style.position = "absolute";
		img.style.left = "3px";
		img.style.top = "3px";
		img.style.backgroundImage = "url("+icon+")";
		img.src = "";
		item.appendChild(img);
		
		var texto = document.createElement('span');
		texto.innerHTML = text;
		item.appendChild(texto);
		
		var iconSubMenu = "";
		if(subMenu.length > 0){
			iconSubMenu = "";
		}
		var subMenu = document.createElement('img');
		subMenu.style.width = "12px";
		subMenu.style.height = "9px";
		subMenu.style.border = "0 none";
		subMenu.style.position = "absolute";
		subMenu.style.right = "0px";
		subMenu.style.top = "7px";
		subMenu.src = iconSubMenu;
		item.appendChild(subMenu);

		return box;
	},
	
	show : function(e){
		var xy = e.xy || {x: e.x, y: e.y};
		
		this.div.style.display = '';
    	this.div.style.top = xy.y+'px';
        this.div.style.left = xy.x+'px';
        OpenLayers.Event.stop(e);
	},

	hide : function(e){
		this.div.style.display = 'none';
		
		if(e){
			OpenLayers.Event.stop(e);
		}
	},
	
	getNodeWidth : function(node){
		var element = node;
		while(element != null){
			if(element.clientWidth && element.clientWidth > 0){
				return element.clientWidth;
			}else{
				element = child.parentNode;
			}
		}
		return 0;
	},
	
	parseMenu : function(root, items){
		var menu = this.createMenu();
		
		if(root.isSubMenu){
			menu.style.display = 'none';
	        OpenLayers.Event.observe(root, "mouseover", OpenLayers.Function.bindAsEventListener(function(e){
	        	menu.style.display = '';
	        	menu.style.top = '0px';
	        	menu.style.left = this.getNodeWidth(root)+'px';
	            OpenLayers.Event.stop(e);
			}, this));
			OpenLayers.Event.observe(root, "mouseout", OpenLayers.Function.bindAsEventListener(function(e){
				menu.style.display = 'none';
				OpenLayers.Event.stop(e);
			}, this));
		}
					
		for(var i = 0; i < items.length; i++){
			if(items[i] == "-"){
				menu.appendChild(this.createSeparator(items[i]));
			}else{
				var child = this.createItem(items[i]);
				menu.appendChild(child);
				if(items[i].menu && items[i].menu.length > 0){
					child.isSubMenu = true;
					this.parseMenu(child, items[i].menu);
				}
			}
		}
		
		root.appendChild(menu);
	},

    CLASS_NAME: "MapService.Control.ContextMenu"
});